home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 05 - 1989 / 05.08 Aug 89 / POOPDraw Code ƒ / LIST ListObject.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-06-12  |  8.5 KB  |  305 lines  |  [TEXT/KAHL]

  1. /********************************************************************/
  2. /*                        SOURCE CODE FILE                            */
  3. /********************************************************************/
  4. /*
  5. *   >>>    File name:        List Object    
  6. *
  7. *      >>>    Purpose:        A universally double list of other objects
  8. *     >>>    Project:        PoopDraw    
  9. *     >>>    Date:            2/20/89
  10. *      >>>    By:                Adam Treister
  11. *
  12. */
  13. /********************************************************************/
  14. /*    For Your Information            1802 Hillside Rd. SB CA 93101    */
  15. /********************************************************************/
  16.  
  17.  
  18. #include "PoopDrawInc"
  19.  
  20. typedef struct
  21. {
  22.     _StdObjectFields
  23.     long    **dataArray;
  24.     int        nElements;
  25.     int        index;            /* keep track for next and prev calls */
  26.     
  27. }    
  28.     ListObjectRec, *ListObjectPtr, **ListObject,**ListObjectHandle;
  29. #define BLOCKSIZE 32L
  30.  
  31. /********************************************************************/
  32. private void ListDispatch(ListObject ObjectH,int Message,LPtr ParmP);
  33. ListObject NewListObject(void);
  34. private void AddObjToList(ListObject List, ObjectHandle ObjectH);
  35. private void AppendToList(ListObject List, ObjectHandle ObjectH);
  36. private void DelObjFromList(ListObject List, ObjectHandle ObjectH);
  37. private void FindObject            (ListObject List,LPtr ParmP);
  38. private void Apply(ListObject List,int Message,LPtr ParmP);
  39. private void Dispose(ListObject List,LPtr ParmP);
  40. private long First(ListObject List);
  41. private long Next(ListObject List);
  42. private long Prev(ListObject List);
  43. private long Last(ListObject List);
  44.  
  45. /********************************************************************/
  46.     
  47. void ListDispatch(ObjectH,Message,ParmP)
  48. ListObject ObjectH;
  49. int Message;
  50. LPtr ParmP;
  51.  
  52. {
  53.     switch(Message)
  54.     {
  55.         case DISPOSE:        Dispose(ObjectH,ParmP);                        break;
  56.  
  57.         case ADDOBJECT:        AddObjToList(ObjectH,ParmP);                    break;
  58.         case APPEND:        AppendToList(ObjectH,ParmP);                    break;
  59.         case DELOBJECT:        DelObjFromList(ObjectH,ParmP);                break;
  60.  
  61.         case FIND:            FindObject(ObjectH,ParmP);            break;
  62.         case CLRSELECT:
  63.         case ERASE:            Apply(ObjectH,INVAL,ParmP);
  64.                             Apply(ObjectH,UNSELECT,ParmP);
  65.                             (*ObjectH)->nElements = 0;                        break;
  66.                             
  67.         case GETSIZE:        *ParmP = (long)     (*ObjectH)->nElements;
  68.                             (*ObjectH)->index = -1;                            break;
  69.         case FIRST:            *ParmP = First(ObjectH);                        break;
  70.         case NEXT:            *ParmP = Next(ObjectH);                        break;
  71.         case PREV:            *ParmP = Prev(ObjectH);                        break;
  72.         case LAST:            *ParmP = Last(ObjectH);                        break;
  73.  
  74.         default:            Apply(ObjectH,Message,ParmP);
  75.     }
  76. }    
  77. /********************************************************************/
  78.  
  79. ListObject NewListObject()
  80. {
  81.     ListObject list;
  82.     list = _GetHandleToRecord(ListObjectRec);
  83.     NullOutHandle(list);
  84.     (*list)->dispatch = ListDispatch;
  85.     (*list)->dataArray = NewHandle(BLOCKSIZE);
  86.     (*list)->nElements = (*list)->index = 0;            /* not nec. because of NullOut */
  87.      (*list)->class = LIST;
  88.     return(list);
  89. }
  90. /*------------------------------------------------------------------*/
  91.  
  92. void Dispose(List,ParmP)
  93. ListObject List;
  94. LPtr ParmP;
  95. {
  96.     long whatToKillFlag = (*ParmP);
  97.     if (ODD(whatToKillFlag))
  98.     {
  99.         Apply(List,DISPOSE,NULL);
  100.         (*List)->nElements = 0;    
  101.     }
  102.     if (whatToKillFlag > 1)
  103.     {    
  104.         DisposeHandle((*List)->dataArray);
  105.         DisposeHandle(List);
  106.     }
  107. }
  108. /* ============================================================ */
  109. /*                                                                */
  110. /*             OBJECT LIST FUNCTIONS                                */
  111. /*                                                                */
  112. /* ============================================================ */
  113.  
  114.  
  115. /* ------------------------------------------------------------ */
  116. /*                                                                */
  117. /*                AddObjToList                                    */
  118. /*                                                                */
  119. /*    This function adds the passed object to the dataArray        */
  120. /*    in the  List's ObjectHandle.                                */
  121. /*                                                                */
  122. /* ------------------------------------------------------------ */
  123.  
  124. void AddObjToList(List, ObjectH)
  125. ListObject List;
  126. ObjectHandle ObjectH;
  127. {
  128.         Size size;
  129.         
  130.     size = GetHandleSize((*List)->dataArray);
  131.     if (size == (*List)->nElements * sizeof(Handle))        /* all spaces are full, add more */
  132.         SetHandleSize((*List)->dataArray,size + BLOCKSIZE);
  133.         
  134.     (*(*List)->dataArray)[(*List)->nElements++] = (long) ObjectH;
  135. }
  136. /* ------------------------------------------------------------ */
  137. /*                                                                */
  138. /*                AddObjToList                                    */
  139. /*                                                                */
  140. /*    This function adds the passed object to the dataArray        */
  141. /*    in the  List's ObjectHandle.                                */
  142. /*                                                                */
  143. /* ------------------------------------------------------------ */
  144.  
  145. void AppendToList(List, ObjectH)
  146. ListObject List;
  147. ObjectHandle ObjectH;
  148. {
  149.         Size size;
  150.         LPtr                array;
  151.         
  152.     size = GetHandleSize((*List)->dataArray);
  153.     if (size == (*List)->nElements * sizeof(Handle))        /* all spaces are full, add more */
  154.         SetHandleSize((*List)->dataArray,size + BLOCKSIZE);
  155.         
  156.     (*(*List)->dataArray)[(*List)->nElements++] = (long) ObjectH;
  157.     array = (*(*List)->dataArray);
  158.     BlockMove(array,array+1,(*List)->nElements * sizeof(Handle));
  159.     (*(*List)->dataArray)[0] = (long) ObjectH;
  160. }
  161.  
  162. /* ------------------------------------------------------------ */
  163. /*                                                                */
  164. /*                    DelObjFromWin                                */
  165. /*                                                                */
  166. /*    Array Delete squeezing following elements downward            */
  167. /*                                                                */
  168. /* ------------------------------------------------------------ */
  169.  
  170. void DelObjFromList(List, ObjectH)
  171. ListObject List;
  172. ObjectHandle ObjectH;
  173.  
  174. {
  175.             Size size;
  176.             LPtr            adr,    array;
  177.             int i;
  178.             
  179.     array = (*(*List)->dataArray);
  180.     size = GetHandleSize((*List)->dataArray);
  181.     
  182.     for (i=0; i < (*List)->nElements; i++)
  183.     {
  184.         if (array[i] == (long) ObjectH)            /* found it!! */
  185.         {
  186.             adr = &array[i];
  187.             BlockMove(adr+1,adr,size - (4L * (i+1)));        /* adr+1 is 4 bytes past adr !!! */
  188.             (*List)->nElements--;
  189.             if (size > ((*List)->nElements * sizeof(Handle)) + BLOCKSIZE)        /* reduce extra space */
  190.                 SetHandleSize((*List)->dataArray,size - BLOCKSIZE);
  191.             return;
  192.         }
  193.     }
  194.  }
  195. /* ------------------------------------------------------------ */
  196. /*                                                                */
  197. /*                FindObject                                        */
  198. /*                                                                */
  199. /*    Like FindWindow or FindControl, this routine goes thru        */
  200. /*    a list, looking for a successful PtInRgn. It puts the         */
  201. /*    frontmost object satisfying the test in objHP                */
  202. /* ------------------------------------------------------------ */
  203. int PtInDrawObjectHandle(Point pt,DrawObjectHandle ObjectH);
  204. Boolean PtInDrawObjectRegion(Point pt,ObjectHandle ObjectH);
  205.  
  206. void FindObject(List,ParmP)
  207. ListObject List;
  208. LPtr ParmP;
  209. {
  210.             ObjectHandle        ObjectH;
  211.             Point                 pt;
  212.             int i;
  213.             LPtr                array;
  214.             RgnHandle            rgn;
  215.             Boolean found = FALSE;
  216.             int where;
  217.             
  218.     array = *(*List)->dataArray;
  219.     pt = *(Point *)ParmP[0];
  220.     for (i=(*List)->nElements-1; i >= 0  AND !found; i--)
  221.     {
  222.         ObjectH = (ObjectHandle) array[i];
  223.         if (BitTst(&(*ObjectH)->attributes,SelectedBit))
  224.         {
  225.             where = PtInDrawObjectHandle(pt,ObjectH);
  226.             if (where == 5)
  227.                 found = PtInDrawObjectRegion( pt, ObjectH);
  228.             else found = where;        /* true for interior or any handle */
  229.         }
  230.         else
  231.             found = PtInDrawObjectRegion( pt, ObjectH);
  232.     }
  233.     ParmP[1] = (found) ? (long) ObjectH : NULL;
  234. }
  235. /*------------------------------------------------------------------*/
  236. Boolean PtInDrawObjectRegion( pt, ObjectH)
  237. Point pt;
  238. ObjectHandle ObjectH;
  239. {
  240.             RgnHandle            rgn;
  241.             Boolean found = FALSE;
  242.  
  243.     rgn = NewRgn();
  244.     OpenRgn();
  245.     Dispatch(ObjectH,FRAME,NULL);
  246.     CloseRgn(rgn);
  247.     found = PtInRgn(pt,rgn);
  248.     DisposeRgn(rgn);
  249.     return(found);
  250. }
  251. /* ------------------------------------------------------------ */
  252. /*                                                                */
  253. /*                Apply                                            */
  254. /*                                                                */
  255. /* ------------------------------------------------------------ */
  256.  
  257. void Apply(List, Message,ParmP)
  258. ListObject List;
  259. int Message;
  260. LPtr ParmP;
  261.  
  262. {
  263.         ObjectHandle        ObjectH,next;
  264.         int i;
  265.             LPtr                array;
  266.         
  267.     array = *(*List)->dataArray;
  268.     for (i=0; i < (*List)->nElements; i++)
  269.     {
  270.         Dispatch((ObjectHandle)array[i],Message,ParmP);
  271.     }
  272. }
  273. /*------------------------------------------------------------------*/
  274.  
  275. long First(List)
  276. ListObject List;
  277. {
  278.     return((*(*List)->dataArray)[0]);
  279. }
  280. /*------------------------------------------------------------------*/
  281. long Next(List)
  282. ListObject List;
  283. {
  284.     if ((*List)->index >= (*List)->nElements-1)
  285.         (*List)->index = 0;
  286.     else (*List)->index++;
  287.     return((*(*List)->dataArray)[(*List)->index]);
  288. }
  289. /*------------------------------------------------------------------*/
  290. long Prev(List)
  291. ListObject List;
  292. {
  293.     if ((*List)->index <= 0)
  294.         (*List)->index = (*List)->nElements-1;
  295.     else (*List)->index--;
  296.     return((*(*List)->dataArray)[(*List)->index]);
  297. }
  298. /*------------------------------------------------------------------*/
  299. long Last(List)
  300. ListObject List;
  301. {
  302.     return((*(*List)->dataArray)[(*List)->nElements-1]);
  303. }
  304. /*------------------------------------------------------------------*/
  305.